/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.formserver.vmmanager.util;

import com.inspur.edp.bef.bizentity.pushchangesetargs.ObjectChangeDetail;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;

import java.util.Map;

public class PushObjectChangeSet {

  public PushObjectChangeSet() {
  }

  public GspViewObject getObjectByID(GspMetadata metadata, String id) {
    GspViewModel entity = (GspViewModel)metadata.getContent();
    return findObjectById(entity.getMainObject(), id);

  }

  private GspViewObject findObjectById(GspViewObject object, String beId) {
    if(object == null && StringUtil.checkNull(beId)) {
      return null;
    }
    if(getObjectByRefId(object, beId)) {
      return object;
    }
    for(IGspCommonObject child: object.getContainChildObjects()) {
      if (getObjectByRefId((GspViewObject)child, beId)){
        return (GspViewObject) child;
      }
      GspViewObject target = findObjectById((GspViewObject) child, beId);
      if(target != null) {
        return target;
      }
    }
    return null;
  }

  private GspViewObject  findParentObjectById(GspViewObject object, String beId) {
    if(object == null && StringUtil.checkNull(beId)) {
      return null;
    }
    for(IGspCommonObject child: object.getContainChildObjects()) {
      if(getObjectByRefId((GspViewObject)child, beId)){
        return object;
      }
      GspViewObject target = findParentObjectById((GspViewObject) child, beId);
      if(target != null) {
        return target;
      }
    }
    return null;
  }

  /**
   * 新增节点
   * @param metadata
   * @param object
   * @param parentId
   */
  public void addObject(GspMetadata metadata, GspViewObject object, String parentId) {
    if(object == null && StringUtil.checkNull(parentId)) {
      return;
    }
    GspViewObject parentObject = getObjectByID(metadata, parentId);
    for (IGspCommonObject child : parentObject.getContainChildObjects()) {
      if(child.getCode() != null && child.getCode().equalsIgnoreCase(object.getCode())) {
        return;
      }
    }
    parentObject.getContainChildObjects().add(object);

  }

  /**
   * 修改节点信息
   * @param destObject
   * @param changeDetail
   */
  public void modifyObject(GspViewObject destObject, ObjectChangeDetail changeDetail) {
    Map<String, Object> changeInfo = changeDetail.getChangeInfo();

    if(destObject == null) {
      return;
    }
    changeInfo.forEach((key,val) -> {
      modifyObjectPropertyValue(key, val, destObject);
    });
  }

  private void modifyObjectPropertyValue(String propertyName, Object propertyValue, GspViewObject destObject) {
    if(propertyName.equals(CommonModelNames.Code)) {
      destObject.setCode((String)propertyValue);
    }
  }

  public void deleteObject(GspMetadata metadata,String refObjectId) {
    GspViewObject parentObject = findParentObjectById(((GspViewModel)metadata.getContent()).getMainObject(), refObjectId);
    if (parentObject != null) {
      parentObject.getContainChildObjects().removeIf(obj ->
          getObjectByRefId((GspViewObject)obj, refObjectId));
    }
  }
  private boolean getObjectByRefId(GspViewObject viewObject, String refId) {
    if (viewObject.getMapping() != null &&
        !StringUtil.checkNull(viewObject.getMapping().getTargetObjId()) &&
        viewObject.getMapping().getTargetObjId().equals(refId)) {
      return true;
    }
    return false;
  }

}
